654
23853
Vuoi migliorare questo post? Fornisci risposte dettagliate a questa domanda, comprese citazioni e una spiegazione del motivo per cui la tua risposta è corretta. Le risposte prive di dettagli sufficienti possono essere modificate o eliminate.
Ho erroneamente aggiunto file a Git utilizzando il comando:
git aggiungi myfile.txt
Non ho ancora eseguito git commit. C'è un modo per annullarlo, in modo che questi file non vengano inclusi nel commit? 
1
2
Il prossimo
Puoi annullare git add prima di eseguire il commit con
git reset 
che lo rimuoverà dall'indice corrente (l'elenco "in fase di commit") senza cambiare nient'altro.
Puoi usare
git reset
senza alcun nome di file per rimuovere tutte le modifiche dovute. Questo può tornare utile quando ci sono troppi file per essere elencati uno per uno in un ragionevole lasso di tempo.
Nelle vecchie versioni di Git, i comandi precedenti sono equivalenti a git reset HEAD  e git reset HEAD rispettivamente, e falliranno se HEAD non è definito (perché non hai ancora effettuato alcun commit nel tuo repository) o ambiguo (perché ha creato un ramo chiamato HEAD, che è una cosa stupida che non dovresti fare). Questo è stato modificato in Git 1.8.2, quindi nelle versioni moderne di Git puoi usare i comandi sopra anche prima di fare il tuo primo commit:
"git reset" (senza opzioni o parametri) utilizzato per l'errore quando
non hai alcun commit nella tua cronologia, ma ora ti dà
un indice vuoto (per corrispondere a commit inesistenti su cui non sei nemmeno).
Documentazione: git reset
|
Tu vuoi:
git rm --cached 
Ragionamento:
Quando ero nuovo a questo, ho provato per la prima volta
git reset.
(per annullare l'intera aggiunta iniziale), solo per ottenere questo messaggio (non così) utile:
fatale: impossibile risolvere "HEAD" come riferimento valido.
Si scopre che questo è dovuto al fatto che il riferimento HEAD (ramo?) Non esiste fino a dopo il primo commit. Cioè, ti imbatterai nel mio stesso problema da principiante se il tuo flusso di lavoro, come il mio, fosse qualcosa del tipo:
cd nella mia nuova fantastica directory del progetto per provare Git, il nuovo hotness
git init
git add.
stato git
... un sacco di pergamene di merda di ...
=> Dannazione, non volevo aggiungere tutto questo.
google "annulla aggiunta git"
=> trova Stack Overflow - yay
git reset.
=> irreversibile: impossibile risolvere "HEAD" come riferimento valido.
Si scopre inoltre che c'è un bug registrato contro l'inutilità di questo nella mailing list.
E che la soluzione corretta fosse proprio lì nell'output di stato di Git (che, sì, ho sorvolato come 'schifezza)
...
# Modifiche da applicare:
# (usa "git rm --cached  ..." per rimuovere lo stage)
...
E la soluzione è davvero usare git rm --cached FILE.
Nota gli avvertimenti altrove qui: git rm cancella la tua copia di lavoro locale del file, ma non se usi --cached. Ecco il risultato di git help rm:
- cache
Utilizzare questa opzione per rimuovere lo stage e rimuovere i percorsi solo dall'indice.
I file dell'albero di lavoro, modificati o meno, verranno lasciati.
Procedo all'uso
git rm --cached.
per rimuovere tutto e ricominciare. Non ha funzionato però, perché mentre aggiungi. è ricorsivo, risulta che rm necessita di -r per ricorrere. Sospiro.
git rm -r --cached.
Ok, ora sono tornato da dove ho iniziato. La prossima volta userò -n per fare un dry run e vedere cosa verrà aggiunto:
git aggiungi -n.
Ho zippato tutto in un posto sicuro prima di fidarmi di git help rm sul fatto che --cached non distruggesse nulla (e se avessi scritto male).
|
Se digiti:
stato git
Git ti dirà cosa è messo in scena, ecc., Incluse le istruzioni su come rimuovere lo stage:
usa "git reset HEAD  ..." per rimuovere lo stage
Trovo che Git faccia un buon lavoro spingendomi a fare la cosa giusta in situazioni come questa.
Nota: le versioni recenti di Git (1.8.4.x) hanno modificato questo messaggio:
(usa "git rm --cached  ..." per rimuovere lo stage)
|
Per chiarire: git add sposta le modifiche dalla directory di lavoro corrente all'area di staging (indice).
Questo processo è chiamato messa in scena. Quindi il comando più naturale per mettere in scena le modifiche (file modificati) è quello ovvio:
fase git
git add è solo un alias più facile da digitare per git stage
Peccato che non ci siano comandi git unstage né git unadd. Quello rilevante è più difficile da indovinare o ricordare, ma è abbastanza ovvio:
git reset HEAD -
Possiamo facilmente creare un alias per questo:
git config --global alias.unadd 'reset HEAD -'
git config --global alias.unstage 'reset HEAD -'
E infine, abbiamo nuovi comandi:
git aggiungi file1
git stage file2
git unadd file2
git unstage file1
Personalmente utilizzo alias ancora più brevi:
git a # Per la messa in scena
git u # Per rimuovere lo stage
|
In aggiunta alla risposta accettata, se il file aggiunto per errore era enorme, probabilmente noterai che, anche dopo averlo rimosso dall'indice con "git reset", sembra ancora occupare spazio nella directory .git.
Non c'è niente di cui preoccuparsi; il file è effettivamente ancora nel repository, ma solo come "oggetto sciolto". Non verrà copiato su altri repository (tramite clone, push) e lo spazio verrà eventualmente recuperato, anche se forse non molto presto. Se sei ansioso, puoi eseguire:
git gc --prune = ora
Aggiornamento (quello che segue è il mio tentativo di cancellare un po 'di confusione che può derivare dalle risposte più votate):
Allora, qual è il vero annullamento di git add?
git resetta HEAD ?
o
git rm --cached ?
A rigor di termini, e se non sbaglio: nessuno.
git add non può essere annullato - in modo sicuro, in generale.
Ricordiamo prima cosa fa git add :
Se  non è stato precedentemente tracciato, git add lo aggiunge ala cache, con il suo contenuto corrente.
Se  era già tracciato, git add salva il contenuto corrente (snapshot, versione) nella cache. In Git, questa azione è ancora chiamata aggiungi, (non semplicemente aggiornala), perché due diverse versioni (istantanee) di un file sono considerate come due elementi diversi: quindi, stiamo effettivamente aggiungendo un nuovo elemento alla cache, per essere eventualmente commesso in seguito.
Alla luce di ciò, la domanda è leggermente ambigua:
Ho aggiunto per errore dei file usando il comando ...
Lo scenario dell'OP sembra essere il primo (file non tracciato), vogliamo che "undo" rimuova il file (non solo il contenuto corrente) dagli elementi tracciati. Se questo è il caso, allora va bene eseguire git rm --cached .
E potremmo anche eseguire git reset HEAD . Questo è in generale preferibile, perché funziona in entrambi gli scenari: fa anche l'annullamento quando abbiamo aggiunto erroneamente una versione di un elemento già tracciato.
Ma ci sono due avvertenze.
Primo: c'è (come sottolineato nella risposta) solo uno scenario in cui git reset HEAD non funziona, ma git rm --cached funziona: un nuovo repository (nessun commit). Ma, davvero, questo è un caso praticamente irrilevante.
Secondo: tieni presente che git reset HEAD non può recuperare magicamente il contenuto del file precedentemente memorizzato nella cache, lo risincronizza semplicemente da HEAD. Se il nostro git add fuorviato ha sovrascritto una versione precedente non salvata, non possiamo ripristinarla. Ecco perché, in senso stretto, non possiamo annullare [*].
Esempio:
$ git init
$ echo "versione 1"> file.txt
$ git add file.txt # Prima aggiunta di file.txt
$ git commit -m 'primo commit'
$ echo "versione 2"> file.txt
$ git add file.txt # Stage (non eseguire il commit) "versione 2" di file.txt
$ git diff --file nella cache.txt
-versione 1
+ versione 2
$ echo "versione 3"> file.txt
$ git diff file.txt
-versione 2
+ versione 3
$ git add file.txt # Oops, non intendevamo questo
$ git reset HEAD file.txt # Annulla?
$ git diff --cached file.txt # Nessun difetto, ovviamente. stage == HEAD
$ git diff file.txt # Abbiamo perso irrevocabilmente la "versione 2"
-versione 1
+ versione 3
Ovviamente, questo non è molto critico se seguiamo il solito flusso di lavoro pigro di fare "git add" solo per aggiungere nuovi file (caso 1) e aggiorniamo i nuovi contenuti tramite il comando commit, git commit -a.
* (Modifica: quanto sopra è praticamente corretto, ma possono ancora esserci alcuni modi leggermente hacker / contorti per recuperare le modifiche che sono state messe in scena, ma non impegnate e poi sovrascritte - vedere i commenti di Johannes Matokic e iolsmit)
|
Annullare un file che è già stato aggiunto è abbastanza facile usando Git. Per ripristinare myfile.txt, che è già stato aggiunto, utilizzare:
git resetta HEAD myfile.txt
Spiegazione:
Dopo aver messo in scena file indesiderati, per annullare, puoi eseguire git reset. Head è l'head del tuo file nel locale e l'ultimo parametro è il nome del tuo file.
Ho creato i passaggi nell'immagine di seguito in modo più dettagliato per te, inclusi tutti i passaggi che possono verificarsi in questi casi:
|
git rm --cached. -r
"annullerà" tutto ciò che hai aggiunto dalla directory corrente in modo ricorsivo
|
Correre
git gui
e rimuovere tutti i file manualmente o selezionandoli tutti e facendo clic sul pulsante unstage from commit.
|
La domanda non è chiaramente posta. Il motivo è che git add ha due significati:
aggiungere un nuovo file all'area di staging, quindi annullare con git rm --cached file.
aggiungere un file modificato all'area di staging, quindi annullare con git reset HEAD file.
In caso di dubbio, utilizzare
git ripristina il file HEAD
Perché fa la cosa prevista in entrambi i casi.
Attenzione: se esegui git rm --cached file su un file che è stato modificato (un file che esisteva prima nel repository), il file verrà rimosso su git commit! Esisterà ancora nel tuo file system, ma se qualcun altro estrae il tuo commit, il file verrà cancellato dal loro albero di lavoro.
git status ti dirà se il file era un file nuovo o modificato:
Sul master di filiale
Modifiche da applicare:
(usa "git reset HEAD  ..." per rimuovere lo stage)
nuovo file: my_new_file.txt
modificato: my_modified_file.txt
|
Git ha comandi per ogni azione immaginabile, ma ha bisogno di una conoscenza approfondita per fare le cose per bene e per questo motivo è contro-intuitivo al massimo ...
Cosa hai fatto prima:
Modificato un file e utilizzato git add. O git add .
Ciò che vuoi:
Rimuovi il file dall'indice, ma mantienilo con versione e lascia le modifiche non salvate nella copia di lavoro:
git resetta HEAD 
Ripristina il file all'ultimo stato da HEAD, annullando le modifiche e rimuovendole dall'indice:
# Pensa a `svn revert ` IIRC.
git resetta HEAD 
git checkout 
# Se hai un "" chiamato come "", usa:
git checkout - 
Ciò è necessario poiché git reset --hard HEAD non funzionerà con singoli file.
Rimuovi  dall'indice e dal controllo delle versioni, mantenendo il file senza versione con le modifiche nella copia di lavoro:
git rm --cached 
Rimuovi completamente  dalla copia di lavoro e dal controllo delle versioni:
git rm 
|
Se sei nel commit iniziale e non puoi usare gitreset, dichiara semplicemente "Git bankruptcy", elimina la cartella .git e ricomincia
|
Come per molte altre risposte, puoi usare git reset
MA:
Ho trovato questo piccolo post fantastico che aggiunge effettivamente il comando Git (beh, un alias) per git unadd: vedi git unadd per i dettagli o ..
Semplicemente,
git config --global alias.unadd "reset HEAD"
Ora puoi
git unadd foo.txt bar.txt
|
Usa git add -i per rimuovere i file appena aggiunti dal tuo commit imminente. Esempio:
Aggiunta del file che non volevi:
$ git add foo
$ git status
# Sul master di filiale
# Modifiche da applicare:
# (usa "git reset HEAD  ..." per rimuovere lo stage)
#
# nuovo file: foo
#
# File non tracciati:
# (usa "git add  ..." per includere in ciò che verrà eseguito il commit)
# [...] #
Entrare in aggiunta interattiva per annullare l'aggiunta (i comandi digitati in git qui sono "r" (revert), "1" (la prima voce nell'elenco mostra revert), "return" per uscire dalla modalità revert e "q" (smettere):
$ git add -i
percorso non organizzato in scena
1: + 1 / -0 niente pippo
*** Comandi ***
1: [s] tatus 2: [u] pdate 3: [r] evert 4: [a] dd untracked
5: [p] atch 6: [d] iff 7: [q] uit 8: [h] elp
E adesso> r
percorso non organizzato in scena
1: + 1 / -0 niente [f] oo
Ripristina >> 1
percorso non organizzato in scena
* 1: + 1 / -0 niente [f] oo
Ripristina >>
nota: foo non è tracciato ora.
ha invertito un percorso
*** Comandi ***
1: [s] tatus 2: [u] pdate 3: [r] evert 4: [a] dd untracked
5: [p] atch 6: [d] iff 7: [q] uit 8: [h] elp
E adesso> q
Ciao.
$
Questo è tutto! Ecco la tua prova, che mostra che "foo" è tornato nell'elenco non monitorato:
$ git status
# Sul master di filiale
# File non tracciati:
# (usa "git add  ..." per includere in ciò che verrà eseguito il commit)
# [...]
# foo
non è stato aggiunto nulla al commit ma sono presenti file non tracciati (usa "git add" per tenere traccia)
$
|
git remove o git rm possono essere usati per questo, con il flag --cached. Provare:
git help rm
|
Ecco un modo per evitare questo fastidioso problema quando inizi un nuovo progetto:
Crea la directory principale per il tuo nuovo progetto.
Esegui git init.
Ora crea un file .gitignore (anche se è vuoto).
Salva il tuo file .gitignore.
Git rende davvero difficile eseguire git reset se non hai commit. Se crei un piccolo commit iniziale solo per il gusto di averne uno, dopo puoi aggiungere -A e git reset tutte le volte che vuoi per ottenere tutto bene.
Un altro vantaggio di questo metodo è che se in seguito incontri problemi di fine riga e devi aggiornare tutti i tuoi file, è facile:
Controlla quel commit iniziale. Questo rimuoverà tutti i tuoi file.
Quindi controlla di nuovo il tuo commit più recente. Questo recupererà nuove copie dei tuoi file, usando le tue attuali impostazioni di fine riga.
|
Forse Git si è evoluto da quando hai pubblicato la tua domanda.
$> git --version
git versione 1.6.2.1
Ora puoi provare:
git resetta HEAD.
Questo dovrebbe essere quello che stai cercando.
|
Notare che se non si specifica una revisione, è necessario includere un separatore. Esempio dalla mia console:
git reset 
fatal: argomento ambiguo '': revisione sconosciuta o percorso non nell'albero di lavoro.
Usa "-" per separare i percorsi dalle revisioni
git reset - 
Modifiche non organizzate dopo il ripristino:
M 
(Git versione 1.7.5.4)
|
Per rimuovere nuovi file dall'area di staging (e solo in caso di un nuovo file), come suggerito sopra:
git rm - FILE nella cache
Usa rm --cached solo per i nuovi file aggiunti accidentalmente.
|
Per ripristinare ogni file in una determinata cartella (e le sue sottocartelle), puoi utilizzare il seguente comando:
git reset *
|
Usa il comando * per gestire più file alla volta:
git reset HEAD * .prj
git ripristina HEAD * .bmp
git ripristina HEAD * gdb *
eccetera.
|
Basta digitare git reset per tornare indietro ed è come se non avessi mai digitato git add. dal tuo ultimo commit. Assicurati di esserti impegnato prima.
|
Supponiamo che crei un nuovo file, newFile.txt:
Supponiamo che io aggiunga il file accidentalmente, git add newFile.txt:
Ora voglio annullare questa aggiunta, prima di eseguire il commit, git reset newFile.txt:
|
Per un file specifico:
git reimposta my_file.txt
git checkout my_file.txt
Per tutti i file aggiunti:
git reset.
git checkout.
Nota: il checkout cambia il codice nei file e passa all'ultimo stato aggiornato (confermato). il ripristino non modifica i codici; ripristina solo l'intestazione.
|
Per annullare git add, usa:
git ripristina il nome del file
|
Questo comando annullerà le modifiche:
git ripristina HEAD nomefile.txt
Puoi anche usare
git aggiungi -p
per aggiungere parti di file.
|
C'è anche la modalità interattiva:
git add -i
Scegli l'opzione 3 per annullare l'aggiunta di file. Nel mio caso spesso voglio aggiungere più di un file e con la modalità interattiva puoi usare numeri come questo per aggiungere file. Questo richiederà tutto tranne 4: 1, 2, 3 e 5
Per scegliere una sequenza, digita 1-5 per prendere tutto da 1 a 5.
File di staging Git
|
git add myfile.txt # Questo aggiungerà il tuo file all'elenco di cui eseguire il commit
Piuttosto opposto a questo comando è,
git reset HEAD myfile.txt # Questo annulleràesso.
quindi, sarai nello stato precedente. Specificato sarà di nuovo nell'elenco non tracciato (stato precedente).
Ripristinerà la tua testa con quel file specificato. quindi, se la tua testa non ce l'ha significa, la resetterà semplicemente.
|
git reimposta nomefile.txt
Rimuoverà un file denominato filename.txt dall'indice corrente, l'area "in procinto di essere impegnato", senza cambiare nient'altro.
|
git reimposta nomefile.txt
Rimuoverà un file denominato filename.txt dall'indice corrente, l'area "in procinto di essere impegnato", senza modificare nient'altro.
|
In Sourcetree puoi farlo facilmente tramite la GUI.
Puoi controllare quale comando Sourcetree usa per rimuovere lo stage di un file.
Ho creato un nuovo file e l'ho aggiunto a Git. Quindi l'ho rimosso dallo stage utilizzando la GUI di Sourcetree.
Questo è il risultato:
Disinstallazione dei file [12/08/15 10:43]
git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetree reset -q - path / to / file / filename.java
Sourcetree utilizza il ripristino per rimuovere lo stage di nuovi file.
|
1
2
Il prossimo
Domanda molto attiva. Guadagna 10 punti reputazione per rispondere a questa domanda. Il requisito di reputazione aiuta a proteggere questa domanda dallo spam e dalle attività di mancata risposta.
Non è la risposta che stai cercando? Sfoglia altre domande contrassegnate con git version-control git-commit git-stage o fai la tua domanda.